package com.light.roller;

import javax.microedition.khronos.opengles.GL10;

import org.anddev.andengine.engine.camera.hud.controls.AnalogOnScreenControl;
import org.anddev.andengine.engine.camera.hud.controls.AnalogOnScreenControl.IAnalogOnScreenControlListener;
import org.anddev.andengine.engine.camera.hud.controls.BaseOnScreenControl;
import org.anddev.andengine.entity.scene.Scene;
import org.anddev.andengine.extension.physics.box2d.PhysicsWorld;
import org.anddev.andengine.opengl.texture.region.TextureRegion;

import android.content.res.Configuration;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;

import com.light.gamecomponents.IGameComponents;

public class AnalogController implements SensorEventListener, IGameComponents {
	
	public enum AnalogControllerState { CONTROLABLE, NOT_CONTROLABLE };
	private TextureRegion m_onScreenControlBaseTextureRegion;
	private TextureRegion m_onScreenControlKnobTextureRegion;
	private AnalogOnScreenControl m_analogOnScreenControl;
	private Roller m_game;
	private Player m_player;
	private AnalogControllerState m_state = AnalogControllerState.NOT_CONTROLABLE;
	public AnalogControllerState getState() { return m_state; }
	public void setState(AnalogControllerState state) { m_state = state; }
	
	public AnalogController(Roller game, Player player)
	{
		super();
		m_game = game;
		m_player = player;
	}
	@Override
	public void onLoadResources()
	{
		ResourceManager.onLoadResources("AnalogController", m_game);
		m_onScreenControlBaseTextureRegion = ResourceManager.getTextureRegion("AnalogControllerBase");
		m_onScreenControlKnobTextureRegion = ResourceManager.getTextureRegion("AnalogControllerKnob");
	}
	
	@Override
	public void unLoadResources() 
	{
		m_onScreenControlBaseTextureRegion = null;
		m_onScreenControlKnobTextureRegion = null;
		ResourceManager.unLoadResources("AnalogController", m_game);
		
	}
	@Override
	public void onLoadScene(Scene scene, PhysicsWorld physicsWorld)
	{
		m_analogOnScreenControl = new AnalogOnScreenControl(0, Roller.CAMERA_HEIGHT - this.m_onScreenControlBaseTextureRegion.getHeight(), Roller.camera, this.m_onScreenControlBaseTextureRegion, this.m_onScreenControlKnobTextureRegion, 0.1f, 200, new IAnalogOnScreenControlListener() {
			@Override
			public void onControlChange(final BaseOnScreenControl pBaseOnScreenControl, final float pValueX, final float pValueY) {
				
			}

			@Override
			public void onControlClick(final AnalogOnScreenControl pAnalogOnScreenControl) {
				
			}
		});
		m_analogOnScreenControl.getControlBase().setBlendFunction(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
		m_analogOnScreenControl.getControlBase().setAlpha(0.5f);
		m_analogOnScreenControl.getControlBase().setScaleCenter(0, 128);
		m_analogOnScreenControl.getControlBase().setScale(1.0f);
		m_analogOnScreenControl.getControlKnob().setScale(1.0f);
		m_analogOnScreenControl.refreshControlKnobPosition();
		scene.setChildScene(m_analogOnScreenControl);
		
	}
	
	@Override
	public void removeFromScene(Scene scene, PhysicsWorld physicsWorld) {
		scene.clearChildScene();
	}
	
	@Override
	public void onAccuracyChanged(Sensor arg0, int arg1) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void onSensorChanged(SensorEvent event) {
		
		Scene scene = m_game.getEngine().getScene();
		if (Roller.orientation == Configuration.ORIENTATION_PORTRAIT)
		{
			if (m_analogOnScreenControl != null && scene != null)
			{
		    	float[] accelerometer_values = event.values.clone();
		    	
		    	if (Math.abs(accelerometer_values[1]) >= Math.abs(accelerometer_values[0]))
		    	{
		    		if (accelerometer_values[1] <= -4.5 && Roller.nowDirection != Direction.LEFT)
		    		{
		    			scene.clearChildScene();
		    			m_analogOnScreenControl = new AnalogOnScreenControl(0, 0, Roller.camera, m_onScreenControlBaseTextureRegion, m_onScreenControlKnobTextureRegion, 0.1f, 200, new IAnalogOnScreenControlListener() {
		    				
		    				@Override
		    				public void onControlChange(final BaseOnScreenControl pBaseOnScreenControl, final float pValueX, final float pValueY) 
		    				{
		    					if (m_state == AnalogControllerState.CONTROLABLE)
		    					{	
			    					if (pValueY >= 0.5f)
			    					{
			    						m_player.walk(0.5f, Direction.DOWN);
			    						m_player.mirrorSprite(true);
			    					}
			    					else if (pValueY <= -0.5f)
			    					{
			    						m_player.walk(0.5f, Direction.UP);
			    						m_player.mirrorSprite(false);
			    					}
			    					else
			    						m_player.walk(0.0f, Direction.UP);
		    					}
		    				}
	
		    				@Override
		    				public void onControlClick(final AnalogOnScreenControl pAnalogOnScreenControl) {
		    					
		    				}		    				
		    			});
		    			
		    			m_analogOnScreenControl.getControlBase().setBlendFunction(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
		    			m_analogOnScreenControl.getControlBase().setAlpha(0.5f);
		    			m_analogOnScreenControl.getControlBase().setScaleCenter(0, 128);
		    			m_analogOnScreenControl.getControlBase().setScale(1.0f);
		    			m_analogOnScreenControl.getControlKnob().setScale(1.0f);
		    			m_analogOnScreenControl.refreshControlKnobPosition();
		    			scene.setChildScene(m_analogOnScreenControl);
		    		}
		    		else if (accelerometer_values[1] > 4.5 && Roller.nowDirection != Direction.RIGHT)
		    		{
		    			scene.clearChildScene();
		    			m_analogOnScreenControl = new AnalogOnScreenControl(Roller.CAMERA_WIDTH - m_onScreenControlBaseTextureRegion.getWidth(), Roller.CAMERA_HEIGHT - m_onScreenControlBaseTextureRegion.getHeight(), Roller.camera, m_onScreenControlBaseTextureRegion, m_onScreenControlKnobTextureRegion, 0.1f, 200, new IAnalogOnScreenControlListener() {
		    				@Override
		    				public void onControlChange(final BaseOnScreenControl pBaseOnScreenControl, final float pValueX, final float pValueY) 
		    				{
		    					if (m_state == AnalogControllerState.CONTROLABLE)
		    					{	
			    					if (pValueY >= 0.5f)
			    					{
			    						m_player.walk(0.5f, Direction.DOWN);
			    						m_player.mirrorSprite(false);
			    					}
			    					else if (pValueY <= -0.5f)
			    					{
			    						m_player.walk(0.5f, Direction.UP);
			    						m_player.mirrorSprite(true);
			    					}
			    					else
			    						m_player.walk(0.0f,Direction.DOWN);
		    					}
		    				}
		    				@Override
		    				public void onControlClick(final AnalogOnScreenControl pAnalogOnScreenControl) {
		    					
		    				}
		    			});
		    			m_analogOnScreenControl.getControlBase().setBlendFunction(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
		    			m_analogOnScreenControl.getControlBase().setAlpha(0.5f);
		    			m_analogOnScreenControl.getControlBase().setScaleCenter(0, 128);
		    			m_analogOnScreenControl.getControlBase().setScale(1.0f);
		    			m_analogOnScreenControl.getControlKnob().setScale(1.0f);
		    			m_analogOnScreenControl.refreshControlKnobPosition();
		    			scene.setChildScene(m_analogOnScreenControl);
		    		}
		    	}
		    	else
		    	{
		    		if (accelerometer_values[0] <= -4.5 && Roller.nowDirection != Direction.DOWN)
		    		{
		    			scene.clearChildScene();
		    			m_analogOnScreenControl = new AnalogOnScreenControl(Roller.CAMERA_WIDTH - m_onScreenControlBaseTextureRegion.getWidth(), 0, Roller.camera, m_onScreenControlBaseTextureRegion, m_onScreenControlKnobTextureRegion, 0.1f, 200, new IAnalogOnScreenControlListener() {
		    				@Override
		    				public void onControlChange(final BaseOnScreenControl pBaseOnScreenControl, final float pValueX, final float pValueY) 
		    				{
		    					if (m_state == AnalogControllerState.CONTROLABLE)
		    					{	
			    					if (pValueX >= 0.5f)
			    					{
			    						m_player.walk(0.5f, Direction.RIGHT);
			    						m_player.mirrorSprite(false);
			    					}
			    					else if (pValueX <= -0.5f)
			    					{
				    					m_player.walk(0.5f, Direction.LEFT);
				    					m_player.mirrorSprite(true);
			    					}
			    					else
			    						m_player.walk(0.0f, Direction.LEFT);
		    					}
		    				}
	
		    				@Override
		    				public void onControlClick(final AnalogOnScreenControl pAnalogOnScreenControl) {
		    					
		    				}
		    			});
		    			m_analogOnScreenControl.getControlBase().setBlendFunction(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
		    			m_analogOnScreenControl.getControlBase().setAlpha(0.5f);
		    			m_analogOnScreenControl.getControlBase().setScaleCenter(0, 128);
		    			m_analogOnScreenControl.getControlBase().setScale(1.0f);
		    			m_analogOnScreenControl.getControlKnob().setScale(1.0f);
		    			m_analogOnScreenControl.refreshControlKnobPosition();
		    			scene.setChildScene(m_analogOnScreenControl);
		    		}
		    		else if (accelerometer_values[0] > 4.5 && Roller.nowDirection != Direction.UP)
		    		{
		    			scene.clearChildScene();
		    			m_analogOnScreenControl = new AnalogOnScreenControl(0, Roller.CAMERA_HEIGHT - m_onScreenControlBaseTextureRegion.getHeight(), Roller.camera, m_onScreenControlBaseTextureRegion, m_onScreenControlKnobTextureRegion, 0.1f, 200, new IAnalogOnScreenControlListener() {
		    				@Override
		    				public void onControlChange(final BaseOnScreenControl pBaseOnScreenControl, final float pValueX, final float pValueY) 
		    				{
		    					if (m_state == AnalogControllerState.CONTROLABLE)
		    					{	
			    					if (pValueX >= 0.5f)
			    					{
			    						m_player.walk(0.5f, Direction.RIGHT);
			    						m_player.mirrorSprite(true);
			    					}
			    					else if (pValueX <= -0.5f)
			    					{
				    					m_player.walk(0.5f, Direction.LEFT);
				    					m_player.mirrorSprite(false);
			    					}
			    					else
			    						m_player.walk(0.0f, Direction.LEFT);
		    					}
		    				}
		    				@Override
		    				public void onControlClick(final AnalogOnScreenControl pAnalogOnScreenControl) {
		    					
		    				}
		    			});
		    			m_analogOnScreenControl.getControlBase().setBlendFunction(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
		    			m_analogOnScreenControl.getControlBase().setAlpha(0.5f);
		    			m_analogOnScreenControl.getControlBase().setScaleCenter(0, 128);
		    			m_analogOnScreenControl.getControlBase().setScale(1.00f);
		    			m_analogOnScreenControl.getControlKnob().setScale(1.00f);
		    			m_analogOnScreenControl.refreshControlKnobPosition();
		    			scene.setChildScene(m_analogOnScreenControl);
		    		}
		    	}
			}
		}
		else
		{
			if (m_analogOnScreenControl != null && scene != null)
			{
		    	float[] accelerometer_values = event.values.clone();
		    	
		    	if (Math.abs(accelerometer_values[1]) >= Math.abs(accelerometer_values[0]))
		    	{
		    		if (accelerometer_values[1] <= -4.5 && Roller.nowDirection != Direction.DOWN)
		    		{
		    			scene.clearChildScene();
		    			m_analogOnScreenControl = new AnalogOnScreenControl(Roller.CAMERA_WIDTH - m_onScreenControlBaseTextureRegion.getWidth(), 0, Roller.camera, m_onScreenControlBaseTextureRegion, m_onScreenControlKnobTextureRegion, 0.1f, 200, new IAnalogOnScreenControlListener() {
		    				@Override
		    				public void onControlChange(final BaseOnScreenControl pBaseOnScreenControl, final float pValueX, final float pValueY) 
		    				{
		    					if (m_state == AnalogControllerState.CONTROLABLE)
		    					{	
			    					if (pValueX >= 0.5f)
			    					{
			    						m_player.walk(0.5f, Direction.RIGHT);
			    						m_player.mirrorSprite(false);
			    					}
			    					else if (pValueX <= -0.5f)
			    					{
				    					m_player.walk(0.5f, Direction.LEFT);
				    					m_player.mirrorSprite(true);
			    					}
			    					else
			    						m_player.walk(0.0f, Direction.LEFT);
		    					}
		    				}
	
		    				@Override
		    				public void onControlClick(final AnalogOnScreenControl pAnalogOnScreenControl) {
		    					
		    				}
		    			});
		    			m_analogOnScreenControl.getControlBase().setBlendFunction(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
		    			m_analogOnScreenControl.getControlBase().setAlpha(0.5f);
		    			m_analogOnScreenControl.getControlBase().setScaleCenter(0, 128);
		    			m_analogOnScreenControl.getControlBase().setScale(1.0f);
		    			m_analogOnScreenControl.getControlKnob().setScale(1.0f);
		    			m_analogOnScreenControl.refreshControlKnobPosition();
		    			scene.setChildScene(m_analogOnScreenControl);
		    		}
		    		else if (accelerometer_values[1] > 4.5 && Roller.nowDirection != Direction.UP)
		    		{
		    			scene.clearChildScene();
		    			m_analogOnScreenControl = new AnalogOnScreenControl(0, Roller.CAMERA_HEIGHT - m_onScreenControlBaseTextureRegion.getHeight(), Roller.camera, m_onScreenControlBaseTextureRegion, m_onScreenControlKnobTextureRegion, 0.1f, 200, new IAnalogOnScreenControlListener() {
		    				@Override
		    				public void onControlChange(final BaseOnScreenControl pBaseOnScreenControl, final float pValueX, final float pValueY) 
		    				{
		    					if (m_state == AnalogControllerState.CONTROLABLE)
		    					{	
		    						if (pValueX >= 0.5f)
			    					{
			    						m_player.walk(0.5f, Direction.RIGHT);
			    						m_player.mirrorSprite(true);
			    					}
			    					else if (pValueX <= -0.5f)
			    					{
				    					m_player.walk(0.5f, Direction.LEFT);
				    					m_player.mirrorSprite(false);
			    					}
			    					else
			    						m_player.walk(0.0f, Direction.LEFT);
		    					}
		    				}
		    				@Override
		    				public void onControlClick(final AnalogOnScreenControl pAnalogOnScreenControl) {
		    					
		    				}
		    			});
		    			m_analogOnScreenControl.getControlBase().setBlendFunction(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
		    			m_analogOnScreenControl.getControlBase().setAlpha(0.5f);
		    			m_analogOnScreenControl.getControlBase().setScaleCenter(0, 128);
		    			m_analogOnScreenControl.getControlBase().setScale(1.0f);
		    			m_analogOnScreenControl.getControlKnob().setScale(1.0f);
		    			m_analogOnScreenControl.refreshControlKnobPosition();
		    			scene.setChildScene(m_analogOnScreenControl);
		    		}
		    	}
		    	else
		    	{
		    		if (accelerometer_values[0] <= -4.5 && Roller.nowDirection != Direction.RIGHT)
		    		{
		    			scene.clearChildScene(); 
		    			m_analogOnScreenControl = new AnalogOnScreenControl(Roller.CAMERA_WIDTH - m_onScreenControlBaseTextureRegion.getWidth(), Roller.CAMERA_HEIGHT - m_onScreenControlBaseTextureRegion.getHeight(), Roller.camera, m_onScreenControlBaseTextureRegion, m_onScreenControlKnobTextureRegion, 0.1f, 200, new IAnalogOnScreenControlListener() {
		    				@Override
		    				public void onControlChange(final BaseOnScreenControl pBaseOnScreenControl, final float pValueX, final float pValueY) 
		    				{
		    					if (m_state == AnalogControllerState.CONTROLABLE)
		    					{	
		    						if (pValueY >= 0.5f)
			    					{
			    						m_player.walk(0.5f, Direction.DOWN);
			    						m_player.mirrorSprite(false);
			    					}
			    					else if (pValueY <= -0.5f)
			    					{
			    						m_player.walk(0.5f, Direction.UP);
			    						m_player.mirrorSprite(true);
			    					}
			    					else
			    						m_player.walk(0.0f,Direction.DOWN);
		    					}
		    				}
	
		    				@Override
		    				public void onControlClick(final AnalogOnScreenControl pAnalogOnScreenControl) {
		    					
		    				}
		    			});
		    			m_analogOnScreenControl.getControlBase().setBlendFunction(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
		    			m_analogOnScreenControl.getControlBase().setAlpha(0.5f);
		    			m_analogOnScreenControl.getControlBase().setScaleCenter(0, 128);
		    			m_analogOnScreenControl.getControlBase().setScale(1.0f);
		    			m_analogOnScreenControl.getControlKnob().setScale(1.0f);
		    			m_analogOnScreenControl.refreshControlKnobPosition();
		    			scene.setChildScene(m_analogOnScreenControl);
		    		}
		    		else if (accelerometer_values[0] > 4.5 && Roller.nowDirection != Direction.LEFT)
		    		{
		    			scene.clearChildScene();
		    			m_analogOnScreenControl = new AnalogOnScreenControl(0, 0, Roller.camera, m_onScreenControlBaseTextureRegion, m_onScreenControlKnobTextureRegion, 0.1f, 200, new IAnalogOnScreenControlListener() {
		    				@Override
		    				public void onControlChange(final BaseOnScreenControl pBaseOnScreenControl, final float pValueX, final float pValueY) 
		    				{
		    					if (m_state == AnalogControllerState.CONTROLABLE)
		    					{	
		    						if (pValueY >= 0.5f)
			    					{
			    						m_player.walk(0.5f, Direction.DOWN);
			    						m_player.mirrorSprite(true);
			    					}
			    					else if (pValueY <= -0.5f)
			    					{
			    						m_player.walk(0.5f, Direction.UP);
			    						m_player.mirrorSprite(false);
			    					}
			    					else
			    						m_player.walk(0.0f, Direction.UP);
		    					}
		    				}
		    				@Override
		    				public void onControlClick(final AnalogOnScreenControl pAnalogOnScreenControl) {
		    					
		    				}
		    			});
		    			m_analogOnScreenControl.getControlBase().setBlendFunction(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
		    			m_analogOnScreenControl.getControlBase().setAlpha(0.5f);
		    			m_analogOnScreenControl.getControlBase().setScaleCenter(0, 128);
		    			m_analogOnScreenControl.getControlBase().setScale(1.00f);
		    			m_analogOnScreenControl.getControlKnob().setScale(1.00f);
		    			m_analogOnScreenControl.refreshControlKnobPosition();
		    			scene.setChildScene(m_analogOnScreenControl);
		    		}
		    	}
			}
		}
	}
	@Override
	public void onLoadEngine() {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void rotate(float angle) {
		// TODO Auto-generated method stub
		
	}



}
